package com.syni.mdd.sjb.common.datatreaure.scan;

import com.syni.mdd.sjb.common.component.utils.common.annotations.CheckParams;
import com.syni.mdd.sjb.common.component.utils.common.annotations.CheckUserIdentity;
import com.syni.mdd.sjb.common.component.utils.common.annotations.EntranceCheck;
import com.syni.mdd.sjb.common.component.utils.common.utils.AopTargetUtils;
import com.syni.mdd.sjb.common.component.utils.redis.utils.RedisTemplateUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @className AuthApiScan
 * @description TOO
 * @Author cfx
 * @DATE 2020/4/11 16:25
 * @VERSION 1.0
 **/
//@Configuration
public class AuthApiScan implements ApplicationListener<ContextRefreshedEvent> {
    private static String API_PREFIX = "/MDD_API";

    @Value("${server.servlet.context-path:}")
    private String ServerPath;

    private static String AUTH_REDIS_KEY = "dsApi:auth:url";

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        String prefix = API_PREFIX + ServerPath;
        Map<String,Object> beansWithAnnotation = contextRefreshedEvent.getApplicationContext().getBeansWithAnnotation(RestController.class);
        if(beansWithAnnotation != null && beansWithAnnotation.size() > 0){
            Set<String> authUrls = new HashSet<>();
            for(Map.Entry<String,Object> entry : beansWithAnnotation.entrySet()){
                //System.out.println(entry.getKey() + ":" + entry.getValue());
                Object origin = AopTargetUtils.getTarget(entry.getValue());
                if(origin == null){
                    return;
                }
                RequestMapping requestMapping = origin.getClass().getAnnotation(RequestMapping.class);
                Method[] methods = origin.getClass().getDeclaredMethods();
                if(methods.length > 0){
                    for(Method method : methods){
                        boolean isCheck = false;
                        if(method.isAnnotationPresent(CheckParams.class)){
                            CheckParams checkParams = method.getAnnotation(CheckParams.class);
                            if(checkParams.checkAuth()){
                                isCheck = true;
                            }
                        }else if(method.isAnnotationPresent(EntranceCheck.class)){
                            EntranceCheck checkParams = method.getAnnotation(EntranceCheck.class);
                            if(checkParams.checkAuth()){
                                isCheck = true;
                            }
                        }else if(method.isAnnotationPresent(CheckUserIdentity.class)){
                            isCheck = true;
                        }
                        if(isCheck){
                            String requestMappingURL = requestMapping.value()[0];
                            if(!requestMappingURL.startsWith("/")){
                                requestMappingURL = "/" + requestMappingURL;
                            }
                            if(method.isAnnotationPresent(PostMapping.class)){
                                PostMapping postMapping = method.getAnnotation(PostMapping.class);
                                String postMappingURL = postMapping.value()[0];
                                if(!postMappingURL.startsWith("/")){
                                    postMappingURL = "/" + postMappingURL;
                                }
                                authUrls.add(prefix + requestMappingURL + postMappingURL);
                            }else if(method.isAnnotationPresent(GetMapping.class)){
                                GetMapping getMapping = method.getAnnotation(GetMapping.class);
                                String getMappingURL = getMapping.value()[0];
                                if(!getMappingURL.startsWith("/")){
                                    getMappingURL = "/" + getMappingURL;
                                }
                                authUrls.add(prefix + requestMappingURL + getMappingURL);
                            }
                        }
                    }
                }
            }
            if(authUrls.size() > 0) {
                RedisTemplateUtils.getRedisTemplate().opsForSet().add(AUTH_REDIS_KEY, authUrls.toArray());
            }
        }
    }
}
